﻿namespace ElisVK.Data.AudioSources
{
    using System.Collections.ObjectModel;
    using Utils;
    using ViewModels;

    public class AudioSource : BindableObject
    {
        #region Data

        static readonly AudioSource DummyChild = new AudioSource();

        private ObservableCollection<AudioSource> _children;

        private string _name;
        bool _isExpanded;
        bool _isSelected;

        #endregion // Data

        #region Constructors

        public AudioSource(string name, AudioSource audioSource)
        {
            Initialize(name, audioSource, false);
        }

        public AudioSource(string name)
        {
            Initialize(name, null, false);
        }

        public AudioSource(string name, bool hasItems)
        {
            Initialize(name, null, hasItems);
        }
        
        // This is used to create the DummyChild instance.
        private AudioSource()
        {
        }

        #endregion // Constructors

        public static ElisVKViewModel ElisVKViewModel { get; set; }

        #region Presentation Members

        public virtual string Name
        {
            get { return _name; }

            set
            {
                if (value == _name)
                    return;

                _name = value;
                OnPropertyChanged("Name");
            }
        }
        
        
        #region Children

        /// <summary>
        /// Returns the logical child items of this object.
        /// </summary>
        public ObservableCollection<AudioSource> Children
        {
            get { return _children; }
        }

        #endregion // Children

        #region HasLoadedChildren

        /// <summary>
        /// Returns true if this object's Children have not yet been populated.
        /// </summary>
        public bool HasDummyChild
        {
            get { return Children.Count == 1 && Children[0] == DummyChild; }
        }

        #endregion // HasLoadedChildren

        #region IsExpanded

        /// <summary>
        /// Gets/sets whether the TreeViewItem 
        /// associated with this object is expanded.
        /// </summary>
        public bool IsExpanded
        {
            get { return _isExpanded; }
            set
            {
                if (value != _isExpanded)
                {
                    _isExpanded = value;
                    OnPropertyChanged("IsExpanded");
                }

                // Expand all the way up to the root.
                if (_isExpanded && Parent != null)
                    Parent.IsExpanded = true;

                // Lazy load the child items, if necessary.
                if (HasDummyChild)
                {
                    Children.Remove(DummyChild);
                    LoadChildren();
                }
            }
        }

        #endregion // IsExpanded

        #region IsSelected

        /// <summary>
        /// Gets/sets whether the TreeViewItem 
        /// associated with this object is selected.
        /// </summary>
        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {
                if (value != _isSelected)
                {
                    _isSelected = value;
                    OnPropertyChanged("IsSelected");

                    if (_isSelected && ElisVKViewModel != null)
                    {
                        ElisVKViewModel.AudioSource = this;
                        ElisVKViewModel.RefreshAudioList();
                    }
                        
                }
            }
        }

        #endregion // IsSelected

        #region LoadChildren

        /// <summary>
        /// Invoked when the child items need to be loaded on demand.
        /// Subclasses can override this to populate the Children collection.
        /// </summary>
        protected virtual void LoadChildren()
        {
        }

        #endregion // LoadChildren

        #region Parent

        public AudioSource Parent { get; private set; }

        #endregion // Parent

        #endregion // Presentation Members

        #region Private members

        private void Initialize(string name, AudioSource parent, bool lazyLoadChildren)
        {
            _name = name;
            Parent = parent;

            _children = new ObservableCollection<AudioSource>();

            if (lazyLoadChildren)
                _children.Add(DummyChild);
        }

        #endregion Private members


        public virtual ObservableCollection<Audio> GetAudios()
        {
            return null;
        }

        public virtual bool Synchronize()
        {
            return false;
        }

        public override string ToString()
        {
            return Name;
        }
    }
}
